package com.it.system.searchservice.dao;

import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.StringUtils;
import com.it.system.educommonapi.entity.Course;
import com.it.system.searchservice.entity.ElasticsearchEntity;
import com.it.system.searchservice.entity.PageEntity;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@Repository
public class ElasticsearchDAO {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 判断索引是否存在
     */
    public boolean existIndex(String indexName) throws IOException {
        //创建索引查询的请求
        GetIndexRequest request = new GetIndexRequest(indexName);
        //判断索引是否存在
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);

        log.info("索引是否存在：{}", indexName, exists);
        return exists;
    }

    /**
     * 删除索引
     */
    public void deleteIndex(String indexName) {
        try {
            // 使用 DeleteIndexRequest 构建请求对象
            DeleteIndexRequest request = new DeleteIndexRequest(indexName);

            // 发送删除请求
            AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
            log.info("删除索引 {} 结果: {}", indexName, delete.isAcknowledged());
        } catch (IOException e) {
            log.error("删除索引失败: {}", indexName, e);
        }
    }

    /**
     * 创建索引
     *
     * @param indexName
     * @throws IOException
     */
    public void createIndex(String indexName) throws IOException {
        //创建索引请求
        CreateIndexRequest request = new CreateIndexRequest(indexName);
        //发送创建索引请求
        CreateIndexResponse response = client.indices().create(request,
                RequestOptions.DEFAULT);
        log.info("{}创建成功");
    }

    /**
     * 查询所有索引
     */
    public void queryAllIndex() throws IOException {
        // 创建查询所有索引的请求
        GetIndexRequest request = new GetIndexRequest("*");
        // 发送查询请求
        org.elasticsearch.client.indices.GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT);
        //获取索引列表
        String[] indices = response.getIndices();
        for (String index : indices) {
            log.info("索引名称：{}", index);
        }
    }

    /**
     * 搜索
     *
     * @param indexName 索引名称
     * @param current   当前页数
     * @param size      分页大小
     * @param search    搜索条件
     * @param sort      排序条件
     * @param clazz     数据类型
     * @return
     */
    public PageEntity search(String indexName, Long current, Long size,
                             Map<String, String> search, Map<String, String> sort,
                             Class clazz) throws IOException {
        //创建搜索请求
        SearchRequest request = new SearchRequest(indexName);
        //创建搜索生成器
        SearchSourceBuilder builder = new SearchSourceBuilder();
        //创建bool查询生成器
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //遍历搜索条件，给bool查询添加搜索条件
        for (String key : search.keySet()) {
            String value = search.get(key);
            if (StringUtils.hasText(value)) {
                //设置过滤器添加短语查询 不分词
                boolQueryBuilder.filter(QueryBuilders.matchPhraseQuery(key, value));
            }
        }
        //设置查询条件
        builder.query(boolQueryBuilder);
        //设置分页参数
        builder.from(current.intValue());
        builder.size(size.intValue());
        //设置排序参数
        if (sort != null && StringUtils.hasText(sort.get("field")) && StringUtils.hasText(sort.get("type"))) {
            String field = sort.get("field");
            String type = sort.get("type");
            builder.sort(new FieldSortBuilder(field).order(SortOrder.fromString(type)));
        }
        //执行搜索
        request.source(builder);
        SearchResponse resp = client.search(request, RequestOptions.DEFAULT);
        List data = new ArrayList();
        for (SearchHit hit : resp.getHits()) {
            //将json转换为Java对象
            Object obj = JSON.parseObject(hit.getSourceAsString(), clazz);
            data.add(obj);
        }
        long totalHits = resp.getHits().getTotalHits().value;
        PageEntity page = new PageEntity(current, size, totalHits, data);

        return page;
    }

    /**
     * 批量导入课程数据到ES
     *
     * @param indexName 索引名称
     * @param courses   课程列表
     * @throws IOException
     */
    public void importCourseData(String indexName, List<Course> courses) throws IOException {
        BulkRequest request = new BulkRequest();

        for (Course course : courses) {
            // 将课程对象转为JSON字符串
            String jsonString = JSON.toJSONString(course);

            // 创建索引请求，指定id和数据
            IndexRequest indexRequest = new IndexRequest(indexName)
                    .id(String.valueOf(course.getId()))
                    .source(jsonString); // 不再需要 XContentType.JSON
            // 添加到批量请求中
            request.add(indexRequest);
        }

        // 执行批量请求
        BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);

        // 记录导入结果
        if (response.hasFailures()) {
            log.error("批量导入数据有错误: {}", response.buildFailureMessage());
        } else {
            log.info("成功导入 {} 条课程数据到索引 {}", courses.size(), indexName);
        }
    }

    /**
     * 保存索引
     *
     * @param indexName
     * @param entity
     * @throws IOException
     */
    public void saveOrUpdate(String indexName, ElasticsearchEntity entity) throws IOException {
        // 使用FastJSON将对象转换为Map
        String jsonString = JSON.toJSONString(entity.getData());
        Map<String, Object> sourceData = JSON.parseObject(jsonString, Map.class);

        IndexRequest request = new IndexRequest(indexName);
        request.id(entity.getId()).source(sourceData);
        client.index(request, RequestOptions.DEFAULT);

        log.info("文档保存成功 {}", entity);
    }


    /**
     * 删除索引
     */
    public void deleteById(String indexName, String id) throws IOException {
        //创建删除文档请求
        DeleteByQueryRequest request = new DeleteByQueryRequest(indexName);
        //设置删除条件
        request.setQuery(QueryBuilders.termQuery("id", id));
        client.deleteByQuery(request, RequestOptions.DEFAULT);
        log.info("文档删除成功 {}", id);
    }


}
